
#include <BasicUsageEnvironment.hh>
#include <getopt.h>

#include "Err.hh"
#include "MediaFormat.hh"
#include "UnicastStreaming.hh"
#include "MulticastStreaming.hh"

VideoFormat videoFormat = VFMT_H264;
int videoBitrate = 1500000;

portNumBits rtspServerPortNum = 8554;

char* streamDescription = strDup("RTSP/RTP stream from a dm365 encoder");
UserAuthenticationDatabase* authDB = NULL;

enum  StreamingMode {
  STREAMING_UNICAST,
  STREAMING_UNICAST_THROUGH_DARWIN,
  STREAMING_MULTICAST_ASM,
  STREAMING_MULTICAST_SSM
};

StreamingMode streamingMode = STREAMING_UNICAST;

int main(int argc, char *argv[])
{
	// Begin by setting up our usage environment:
	TaskScheduler* scheduler = BasicTaskScheduler::createNew();
	UsageEnvironment* env = BasicUsageEnvironment::createNew(*scheduler);

	// Print an introduction message:
	*env << "A streaming server for the DM365 encoder driver\n";
	*env << "Built using \"LIVE555 Streaming Media\": <http://www.live555.com/liveMedia/>\n";

	MediaInput* inputDevice = MediaInput::createNew(*env);
	if (inputDevice == NULL) {
		err(*env) << "Failed to create Media input device\n";
		exit(1);
	}

	// Create the RTSP server:
	RTSPServer* rtspServer = NULL;

	// Normal case: Streaming from a built-in RTSP server:
	rtspServer = RTSPServer::createNew(*env, rtspServerPortNum, authDB);
	if (rtspServer == NULL) {
		*env << "Failed to create RTSP server: " << env->getResultMsg() << "\n";
		exit(1);
	}

	*env << "...done initializing\n";

	// Create a record describing the media to be streamed:
	ServerMediaSession* sms = ServerMediaSession::createNew(*env, "h264", NULL, streamDescription,
				      streamingMode == STREAMING_MULTICAST_SSM);
	rtspServer->addServerMediaSession(sms);
	char *url = rtspServer->rtspURL(sms);
	*env << "Play this stream using the URL:\n" << url << "\n";
	delete[] url;

	// Configure it for unicast or multicast streaming:
	if (streamingMode == STREAMING_UNICAST) {
		setupUnicastStreaming(*inputDevice, sms);
	} else {
		setupMulticastStreaming(*inputDevice, sms);
	}

	// Begin the LIVE555 event loop:
	env->taskScheduler().doEventLoop(); // does not return

	// If "doEventLoop()" *did* return, we'd now do this to reclaim resources before exiting:
	if (streamingMode != STREAMING_UNICAST && streamingMode != STREAMING_UNICAST_THROUGH_DARWIN) {
		reclaimMulticastStreaming();
	}
	Medium::close(rtspServer); // will also reclaim "sms" and its "ServerMediaSubsession"s
	Medium::close(inputDevice);
	env->reclaim();
	delete scheduler;

	return 0;
}
